/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data.email;

import busEvents.CloseWaitingWindowEvent;
import busEvents.OpenWaitingWindowEvent;
import busEvents.StartSearchEvent;
import busEvents.UpdateProgressBar;
import com.adamtaft.eb.EventBusService;
import data.email.EmailMessage;
import enums.EmailMessagePart;
import enums.SortOrder;
import java.util.*;
import javax.mail.Folder;
import javax.mail.Message;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import connection.*;
import javax.mail.FetchProfile;
import javax.mail.UIDFolder;
import javax.mail.internet.MimeMultipart;

/**
 * Třída reprezentjící IMAP složku.
 * @author Arcanis
 */
public class EmailFolder extends Observable {

    private Account account = null;
    private Folder connectedFolder = null;
    private boolean holdsFolders = false;
    private String name;
    private List<EmailMessage> messages = null; //sem můžeš dát jakoukoli kolekci budeš potřebovat
    private List<EmailFolder> folders = null;

    /**
     * In order to create folder
     *
     * @param name
     */
    public EmailFolder(String name) {
        this.name = name;
    }

    public EmailFolder(Folder storeFolder, Account acc) throws Exception {
        this.account = acc;
        this.connectedFolder = storeFolder;
        this.name = storeFolder.getName();
        this.holdsFolders = (storeFolder.getType() == Folder.HOLDS_FOLDERS);

        if (this.holdsFolders) {
            // folders
            this.folders = new LinkedList<>();
            for (Folder f : storeFolder.list()) {
                this.folders.add(new EmailFolder(f, acc));
            }
        } else {
            // messages
            this.connectToFolder();
            this.messages = new LinkedList<>();
            
            Message[] msgs = storeFolder.getMessages();
            FetchProfile fp = new FetchProfile();
            fp.add(FetchProfile.Item.ENVELOPE);
            fp.add(UIDFolder.FetchProfileItem.FLAGS);
            fp.add(UIDFolder.FetchProfileItem.CONTENT_INFO);
            fp.add("X-mailer");
            storeFolder.fetch(msgs, fp);

            for (Message m : msgs) {
                this.messages.add(new EmailMessage(m, acc, this));
            }
            this.disconnectFromFolder();
        }
    }

    void connectToFolder() throws Exception {
        if (!this.connectedFolder.isOpen()) {
            this.connectedFolder.open(Folder.READ_WRITE);
        }
    }

    void disconnectFromFolder() throws Exception {
        if (this.connectedFolder.isOpen()) {
            this.connectedFolder.close(true);
        }
    }

    public void addMessage(EmailMessage message) {
        messages.add(message);
        setChanged();
    }

    public void deleteMessage(EmailMessage message) {
        messages.remove(message);
        setChanged();
    }

    public List<EmailMessage> getMessages() {
        //Testing function
        return messages;
    }

    public List<EmailMessage> getMessages(EmailMessagePart[] searchType, String searched) {
        //@TODO Necka - vrátí list všech zpráv, jejichž jednotlivé části určené v poli searchType obsahují searched.
        //v searchType (podívej se do toho enumu) Můžou být jen části zprávy které mají Searchable = true, ostatní pole prostě odignoruj
        //pořadí nehraje roli, srovná si to pak GridView        

        //můžeš použít (jestli budeš využívat třeba vlákna):
        //EventBusService.publish(new OpenWaitingWindowEvent("Hledání")); //pokud nepoužiješ progressBar
        //EventBusService.publish(new OpenWaitingWindowEvent("Hledání",100)); //pokud použiješ progressBar
        //EventBusService.publish(new UpdateProgressBar(20));
        //EventBusService.publish(new CloseWaitingWindowEvent());
        throw new NotImplementedException();
    }

    public void clearFolder() {
        messages.clear();
        setChanged();
    }

    public void setName(String name) {
        this.name = name;
        setChanged();
    }

    public String getName() {
        return name;
    }
}
